﻿using System;
using System.Collections.Generic;
using FastNet.BusinessSystem.Exceptions;
using SampleBusiness.Objects;

namespace SampleUI
{
    internal static class AddressManagement
    {
        public static void Run()
        {
            while (true)
            {
                Console.Clear();
                Console.ForegroundColor = ConsoleColor.White;

                Console.WriteLine("Please select an option:");
                Console.WriteLine();
                Console.WriteLine("0) Main Menu");
                Console.WriteLine();
                Console.WriteLine("1) Add New Address");
                Console.WriteLine("2) Show Address Details");
                Console.WriteLine("3) Delete Address");
                Console.WriteLine("4) List All Addresses");
                Console.WriteLine();

                switch (Console.ReadKey().KeyChar)
                {
                    case '1':
                        AddAddress();
                        break;
                    case '2':
                        RetrieveAddressId();
                        break;
                    case '3':
                        DeleteAddressId();
                        break;
                    case '4':
                        RetrieveAllAddresses();
                        break;
                    case '0':
                        return;
                }
                Console.WriteLine("");
            }
        }

        private static void AddAddress()
        {
            Console.Clear();
            Common.WriteTitle("Add Address");
            Console.WriteLine("Please enter the details of the new address:");

            Address address = SampleBusiness.SampleBusinessFactory.AddressManager.Create();
            bool firstTime = true;

            while (firstTime || !address.IsValid)
            {
                Console.WriteLine();
                if (firstTime || !string.IsNullOrEmpty(address["AddressLine1"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", address["AddressLine1"]);

                    Console.Write("Address Line 1: ");
                    address.AddressLine1 = Console.ReadLine();
                }

                if (firstTime || !string.IsNullOrEmpty(address["AddressLine2"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", address["AddressLine2"]);

                    Console.Write("Address Line 2: ");
                    address.AddressLine2 = Console.ReadLine();
                }

                if (firstTime || !string.IsNullOrEmpty(address["AddressLine3"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", address["AddressLine3"]);

                    Console.Write("Address Line 3: ");
                    address.AddressLine3 = Console.ReadLine();
                }

                if (firstTime || !string.IsNullOrEmpty(address["City"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", address["City"]);

                    Console.Write("City: ");
                    address.City = Console.ReadLine();
                }

                if (firstTime || !string.IsNullOrEmpty(address["State"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", address["State"]);

                    Console.Write("State: ");
                    address.State = Console.ReadLine();
                }

                if (firstTime || !string.IsNullOrEmpty(address["ZipCode"]))
                {
                    if (!firstTime)
                        Common.WriteError("* The following errors were found: \n\n {0}", address["ZipCode"]);

                    Console.Write("Zip Code: ");
                    address.ZipCode = Console.ReadLine();
                }

                firstTime = false;
            }

            try
            {
                if (address.CanSave)
                    address.SaveChanges();
                Common.WriteSuccess("Address has been saved. You can refer to address ID: \n\t{0}", address.Id);
            }
            catch (BusinessSaveException ex)
            {
                Common.WriteError("There was an error saving the new address to the database: {0}", ex.Message);
            }

            Common.WaitForAnyKey();
        }

        private static void RetrieveAddressId()
        {
            Console.Clear();
            Common.WriteTitle("Retrieve Address");

            Address address;
            while (true)
            {
                Console.Write("Please enter the ID of the address: ");
                string addressId = Console.ReadLine();
                if (string.IsNullOrEmpty(addressId))
                {
                    Common.WriteError("There was no value entered. Please try again.");
                    continue;
                }

                Guid id;
                if (!Guid.TryParse(addressId, out id))
                {
                    Common.WriteError("Value was not of the correct type. Guid expected.");
                    continue;
                }

                try
                {
                    address = SampleBusiness.SampleBusinessFactory.AddressManager.Retrieve(id);
                    break;
                }
                catch (BusinessRetrieveException ex)
                {
                    Common.WriteError("Unable to retrieve Address: {0}", ex.Message);
                }
            }

            PrintAddress(address);

            Common.WaitForAnyKey();
        }

        private static void DeleteAddressId()
        {
            Console.Clear();
            Common.WriteTitle("Delete Address");

            Address address;

            while (true)
            {
                Console.Write("Please enter the ID of the address: ");

                string addressId = Console.ReadLine();
                if (string.IsNullOrEmpty(addressId))
                {
                    Common.WriteError("There was no value entered. Please try again.");
                    continue;
                }

                Guid id;
                if (!Guid.TryParse(addressId, out id))
                {
                    Common.WriteError("Value was not of the correct type. Number expected.");
                    continue;
                }

                try
                {
                    address = SampleBusiness.SampleBusinessFactory.AddressManager.Retrieve(id);

                    if (address != null)
                        break;

                    Common.WriteError("Address not found");
                }
                catch (BusinessRetrieveException ex)
                {
                    Common.WriteError("Unable to retrieve Address: \n\t{0}", ex.Message);
                }
            }

            try
            {
                address.Delete();
                Common.WriteSuccess("Address has been deleted.");
            }
            catch (BusinessDeleteException ex)
            {
                Common.WriteError("Unable to delete Address: \n\t{0}", ex.Message);
            }

            Common.WaitForAnyKey();
        }

        private static void RetrieveAllAddresses()
        {
            Console.Clear();
            Common.WriteTitle("Retrieve All Addresses");

            IList<Address> addresses = SampleBusiness.SampleBusinessFactory.AddressManager.Retrieve();

            foreach (Address address in addresses)
                PrintAddress(address);

            Common.WaitForAnyKey();
        }

        private static void PrintAddress(Address address)
        {
            Console.WriteLine();
            Console.WriteLine("            ID: {0}", address.Id);
            Console.WriteLine("Address Line 1: {0}", address.AddressLine1);
            Console.WriteLine("Address Line 2: {0}", address.AddressLine2);
            Console.WriteLine("Address Line 3: {0}", address.AddressLine3);
            Console.WriteLine("          City: {0}", address.City);
            Console.WriteLine("         State: {0}", address.State);
            Console.WriteLine("      Zip Code: {0}", address.ZipCode);
        }
    }
}
